﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

// Basic global alias for the main class containing constants
using r = Rougeliek.Rougeliek;

namespace Rougeliek
{
    class ScreenBuffer
    {
        public static List<ScreenTile> screenBuffer = new List<ScreenTile>();

        // Initialise screen buffer list, clear the screen, make it
        // ready for drawing
        public static void initBuffer()
        {
            Console.ResetColor();
            Console.Clear();
            screenBuffer.Clear();
        }

        // Load background and foreground (in that order) into a list
        // object for easy rendering
        public static void fillBuffer()
        {
            // Clear the existing buffer
            screenBuffer.Clear();

            // For each of the layers, add them to a single screenBuffer list object
            foreach (Grass grass in Map.foliage) { screenBuffer.Add(new ScreenTile(grass.grassX, grass.grassY, grass.grassSprite, false, ConsoleColor.DarkGray)); }
            foreach (Tree tree in Map.trees) { screenBuffer.Add(new ScreenTile(tree.treeX, tree.treeY, tree.treeSprite, true, ConsoleColor.Gray)); }
            screenBuffer.Add(new ScreenTile(r.M.x, r.M.y, r.M.sprite, false, ConsoleColor.White));
            screenBuffer.Add(new ScreenTile(r.pc.x, r.pc.y, r.pc.sprite, false, ConsoleColor.White));
        }

        // Render the full buffer to the console window
        // -- VERY -- slow and choppy, avoid unless necessary
        public static void drawBuffer()
        {
            fillBuffer();           // Fill the buffer with goodies
            Console.ResetColor();   // Prepare the colours for what's loaded in the buffer

            // For every tile loaded into the buffer by fillBuffer(), output it
            // to the tile's designated coordinates
            foreach (ScreenTile tile in screenBuffer)
            {
                Console.SetCursorPosition(tile.tileX, tile.tileY);
                Console.ForegroundColor = tile.tileFGColour;
                Console.Write(tile.tileSprite);
            }

            // Overlay the game's UI to the screen
            UI.drawUI();
        }

        // Similar to the drawBuffer method above, but this method
        // specifically only renders the designated tile coordinates
        public static void drawBufferTile(int x, int y)
        {
            screenBuffer.Clear();               // Clear the existing buffer
            fillBuffer();                       // Fill it with an updated list

            Console.SetCursorPosition(x,y);     // Go to the designated coordinates 
            Console.Write(" ");                 // And render a blank space to work ontop of

            // Check every tile in the screenBuffer list object for a tile
            // with matching x/y coordinates
            foreach (ScreenTile tile in screenBuffer)
            {
                if (tile.tileX == x && tile.tileY == y)
                {
                    // If a tile is found matching the coordinates, redraw it
                    Console.SetCursorPosition(tile.tileX, tile.tileY);
                    Console.ForegroundColor = tile.tileFGColour;
                    Console.Write(tile.tileSprite);
                }
            }
            
            // This time find the coordinates that match the player's position
            foreach (ScreenTile tile in screenBuffer)
            {
                if (tile.tileX == r.pc.x && tile.tileY == r.pc.y)
                {
                    // And output it to the new coordinates
                    Console.SetCursorPosition(tile.tileX, tile.tileY);
                    Console.ForegroundColor = tile.tileFGColour;
                    Console.Write(tile.tileSprite);
                }
            }

            // This time find the coordinates that match the player's position
            foreach (ScreenTile tile in screenBuffer)
            {
                if (tile.tileX == r.M.x && tile.tileY == r.M.y)
                {
                    // And output it to the new coordinates
                    Console.SetCursorPosition(tile.tileX, tile.tileY);
                    Console.ForegroundColor = tile.tileFGColour;
                    Console.Write(tile.tileSprite);
                }
            }

            UI.uiCursor();
        }

    }

    // Generic tile class to be used for the screenBuffer list object
    class ScreenTile
    {
        public int tileX, tileY;
        public char tileSprite;
        public bool tileSolid;
        public System.ConsoleColor tileFGColour;

        public ScreenTile(int x, int y, char sprite, bool solid, System.ConsoleColor fgcolour)
        {
            tileX = x;
            tileY = y;
            tileSprite = sprite;
            tileSolid = solid;

            // If the tile is designated as being solid, add it to the existing
            // collision array, allows for dynamic solid objects
            if (solid == true)          
            {                           
                Map.collisionGrid[x, y] = (solid == true) ? true : false;
            }
            tileFGColour = fgcolour;
        }
    }
}

